package uri.tcc.fss.alljoyn;

import tcc.uri.fss.engine.ControlApplication;
import uri.tcc.fss.utils.Constantes;
import uri.tcc.fss.utils.Observable;
import uri.tcc.fss.utils.Observer;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

public class AlljoynService extends Service implements Observer {

	private ControlApplication controlApplication;
	private BackgroundHandler backgroundHandler;

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		startBusThread();
		controlApplication = (ControlApplication) getApplication();
		controlApplication.addObserver(this);
	}

	@Override
	public void onDestroy() {
		backgroundHandler.cancelDiscovery();
		backgroundHandler.disconnect();
		backgroundHandler.exit();
		super.onDestroy();
	}

	@Override
	public synchronized void update(Observable o, Object arg) {
		String mensagem = arg.toString();

	}

	private void startBusThread() {
		HandlerThread busThread = new HandlerThread("Backgroundhandler");
		busThread.start();
		backgroundHandler = new BackgroundHandler(busThread.getLooper());
	}

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case Constantes.HANDLE_APPLICATION_QUIT_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): APPLICATION_QUIT_EVENT");
				backgroundHandler.leaveSession();
				backgroundHandler.cancelAdvertise();
				backgroundHandler.unbindSession();
				backgroundHandler.releaseName();
				backgroundHandler.exit();
				stopSelf();
			}
				break;
			case Constantes.HANDLE_USE_JOIN_CHANNEL_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): USE_JOIN_CHANNEL_EVENT");
				backgroundHandler.joinSession();
			}
				break;
			case Constantes.HANDLE_USE_LEAVE_CHANNEL_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): USE_LEAVE_CHANNEL_EVENT");
				backgroundHandler.leaveSession();
			}
				break;
			case Constantes.HANDLE_HOST_INIT_CHANNEL_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): HOST_INIT_CHANNEL_EVENT");
			}
				break;
			case Constantes.HANDLE_HOST_START_CHANNEL_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): HOST_START_CHANNEL_EVENT");
				backgroundHandler.requestName();
				backgroundHandler.bindSession();
				backgroundHandler.advertise();
			}
				break;
			case Constantes.HANDLE_HOST_STOP_CHANNEL_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): HOST_STOP_CHANNEL_EVENT");
				backgroundHandler.cancelAdvertise();
				backgroundHandler.unbindSession();
				backgroundHandler.releaseName();
			}
				break;
			case Constantes.HANDLE_OUTBOUND_CHANGED_EVENT: {
				Log.i(Constantes.TAG_SERVICE,
						"mHandler.handleMessage(): OUTBOUND_CHANGED_EVENT");
				backgroundHandler.sendMessages();
			}
				break;
			default:
				break;
			}
		}
	};

	private final class BackgroundHandler extends Handler {
		private Message msg;

		public BackgroundHandler(Looper looper) {
			super(looper);
		}

		public void exit() {
			msg = backgroundHandler.obtainMessage(Constantes.EXIT);
			backgroundHandler.sendMessage(msg);
		}

		public void connect() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.connect()");
			Message msg = backgroundHandler.obtainMessage(Constantes.CONNECT);
			backgroundHandler.sendMessage(msg);
		}

		public void disconnect() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.disconnect()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.DISCONNECT);
			backgroundHandler.sendMessage(msg);
		}

		public void startDiscovery() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.startDiscovery()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.START_DISCOVERY);
			backgroundHandler.sendMessage(msg);
		}

		public void cancelDiscovery() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.stopDiscovery()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.CANCEL_DISCOVERY);
			backgroundHandler.sendMessage(msg);
		}

		public void requestName() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.requestName()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.REQUEST_NAME);
			backgroundHandler.sendMessage(msg);
		}

		public void releaseName() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.releaseName()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.RELEASE_NAME);
			backgroundHandler.sendMessage(msg);
		}

		public void bindSession() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.bindSession()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.BIND_SESSION);
			backgroundHandler.sendMessage(msg);
		}

		public void unbindSession() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.unbindSession()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.UNBIND_SESSION);
			backgroundHandler.sendMessage(msg);
		}

		public void advertise() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.advertise()");
			Message msg = backgroundHandler.obtainMessage(Constantes.ADVERTISE);
			backgroundHandler.sendMessage(msg);
		}

		public void cancelAdvertise() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.cancelAdvertise()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.CANCEL_ADVERTISE);
			backgroundHandler.sendMessage(msg);
		}

		public void joinSession() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.joinSession()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.JOIN_SESSION);
			backgroundHandler.sendMessage(msg);
		}

		public void leaveSession() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.leaveSession()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.LEAVE_SESSION);
			backgroundHandler.sendMessage(msg);
		}

		public void sendMessages() {
			Log.i(Constantes.TAG_SERVICE, "backgroundHandler.sendMessages()");
			Message msg = backgroundHandler
					.obtainMessage(Constantes.SEND_MESSAGES);
			backgroundHandler.sendMessage(msg);
		}

		/**
		 * The message handler for the worker thread that handles background
		 * tasks for the AllJoyn bus.
		 */
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case Constantes.CONNECT:
				doConnect();
				break;
			case Constantes.DISCONNECT:
				doDisconnect();
				break;
			case Constantes.START_DISCOVERY:
				doStartDiscovery();
				break;
			case Constantes.CANCEL_DISCOVERY:
				doStopDiscovery();
				break;
			case Constantes.REQUEST_NAME:
				doRequestName();
				break;
			case Constantes.RELEASE_NAME:
				doReleaseName();
				break;
			case Constantes.BIND_SESSION:
				doBindSession();
				break;
			case Constantes.UNBIND_SESSION:
				doUnbindSession();
				break;
			case Constantes.ADVERTISE:
				doAdvertise();
				break;
			case Constantes.CANCEL_ADVERTISE:
				doCancelAdvertise();
				break;
			case Constantes.JOIN_SESSION:
				doJoinSession();
				break;
			case Constantes.LEAVE_SESSION:
				doLeaveSession();
				break;
			case Constantes.SEND_MESSAGES:
				doSendMessages();
				break;
			case Constantes.EXIT:
				getLooper().quit();
				break;
			default:
				break;
			}
		}

	}

	public void doConnect() {
		// TODO Auto-generated method stub

	}

	public void doSendMessages() {
		// TODO Auto-generated method stub

	}

	public void doLeaveSession() {
		// TODO Auto-generated method stub

	}

	public void doJoinSession() {
		// TODO Auto-generated method stub

	}

	public void doCancelAdvertise() {
		// TODO Auto-generated method stub

	}

	public void doAdvertise() {
		// TODO Auto-generated method stub

	}

	public void doUnbindSession() {
		// TODO Auto-generated method stub

	}

	public void doBindSession() {
		// TODO Auto-generated method stub

	}

	public void doReleaseName() {
		// TODO Auto-generated method stub

	}

	public void doRequestName() {
		// TODO Auto-generated method stub

	}

	public void doStopDiscovery() {
		// TODO Auto-generated method stub

	}

	public void doStartDiscovery() {
		// TODO Auto-generated method stub

	}

	public void doDisconnect() {
		// TODO Auto-generated method stub

	}

}
